<script>
import T from "ant-design-vue/es/table/Table";
export default {
  name: "CustomTable",
  components: {},
  props: Object.assign({}, T.props, {
    showAlert: {
      type: Boolean,
      default: true
    },
    showPagination: {
      type: Boolean,
      default: true
    },
    showSelection: {
      type: Boolean,
      default: true
    },
    selectionType: {
      type: String,
      default: 'checkbox'
    },
    rowKey: {
      type: String,
      default: "id"
    },
    pageSizeOptions: {
     type: Array,
     default: ()=>['10','20','30','40']
    },
    dataSource: {
      type: [Object, Array],
      required: true,
      default() {
        return {
          total: 0,
          current: 1,
          size: 10,
          records: []
        };
      }
    },
    hideColumns: {
      type: Array,
      default() {
        return [];
      }
    },
    onChange: {
      type: Function,
      default: null
    },
    onRowClick: {
      type: Function,
      default: null
    }
  }),
  data() {
    return {
      selectedRows: [],
      selectedRowKeys: []
    };
  },
  computed: {
    pageInfo() {
      return {
        showSizeChanger: true,
        showQuickJumper: true,
        total: Number(this.dataSource.total) || 0,
        current:
          Number(this.dataSource.pageNo || this.dataSource.current) || 1,
        pageSize: Number(this.dataSource.pageSize || this.dataSource.size) || 10,
        pageSizeOptions:this.pageSizeOptions,
        itemRender:this.itemRender,
      };
    },
    customColumns: state => {
      if (state.hideColumns && state.hideColumns.length > 0) {
        return state.columns.filter(item => {
          if (item.dataIndex) {
            return !state.hideColumns.includes(item.dataIndex);
          } else if (item.title) {
            return !state.hideColumns.includes(item.title);
          } else {
            return true;
          }
        });
      } else {
        return state.columns;
      }
    }
  },
  methods: {
    itemRender(current, type, originalElement) {
        if (type === 'prev') {
          return <a><i aria-label="图标: left" class="anticon anticon-left"><svg viewBox="64 64 896 896" data-icon="left" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 0 0 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"></path></svg></i>上一页</a>;
        } else if (type === 'next') {
          return <a>下一页<i aria-label="图标: right" class="anticon anticon-right"><svg viewBox="64 64 896 896" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"></path></svg></i></a>;
        }
        return originalElement;
    },
    getSelectedRowKeys() {
      return this.selectedRowKeys;
    },
    getSelectedRows() {
      return this.selectedRows;
    },
    onClearRowKeys() {
      // 清空选中内容
      this.selectedRowKeys = [];
      this.selectedRows = [];
    },
    onSelectChange(selectedRowKeys, selectedRows) {
      // 选中内容
      this.selectedRowKeys = selectedRowKeys;
      if (this.rowKey) {
        // 分页数据选择selectedRows只返回当前页的数据，需要特殊处理。1合并数据，2过滤出已选中的数据，3去重
        let map = new Map();
        this.selectedRows = [...this.selectedRows, ...selectedRows]
          .filter(item => this.selectedRowKeys.includes(item[this.rowKey]))
          .reduce((item, next) => {
            if (!map.has(next[this.rowKey])) {
              map.set(next[this.rowKey], true);
              item.push(next);
            }
            return item;
          }, []);
      }
      this.$emit("selectedRow", this.selectedRowKeys);
    },
    onSelect(record, selected, selectedRows, nativeEvent) {
      this.$emit('rowSelect', record)
    },
    onTableChange(pagination, filters, sorter) {
      // 表格分页、过滤、排序变化的时候触发change回调
      const query = {
        pageNo: pagination.current,
        pageSize: pagination.pageSize,
        sortField: sorter.field,
        sortOrder: sorter.order,
        ...filters
      };
      this.onChange && this.onChange(query);
      this.$emit("change", query);
    },
    onCustomRow(record) {
      return {
        on: {
          click: e => {
            e.preventDefault();

            this.onRowClick && this.onRowClick(record);
            this.$emit("rowClick", record);
          }
        }
      };
    },
    renderAlert() {
      // 绘制统计列数据
      return (
        <a-alert class="table-alert">
          <div slot="message" class="table-alert-info">
            <div class="table-alert-info-content">
              <span style="margin-right: 12px">
                已选择{" "}
                <a style="font-weight: 600">{this.selectedRowKeys.length}</a> 项
              </span>
            </div>
            {this.selectedRowKeys.length > 0 && (
              <div class="table-alert-info-option">
                <a onClick={this.onClearRowKeys}>清空</a>
              </div>
            )}
          </div>
        </a-alert>
      );
    }
  },
  render() {
    const {
      showAlert,
      showPagination,
      showSelection,
      dataSource,
      onTableChange,
      pageInfo
    } = this;
    const rowSelection = {
      selectedRowKeys: this.selectedRowKeys,
      onChange: this.onSelectChange,
      type: this.selectionType,
      onSelect: this.onSelect
    };
    let props = {};
    Object.keys(T.props).forEach(key => {
      if (key === "dataSource") {
        props[key] =
          dataSource instanceof Array ? dataSource : dataSource.records;
      } else if (key === "rowSelection") {
        props[key] = showSelection ? rowSelection : null;
      } else if (key === "pagination") {
        props[key] =
          showPagination && !(dataSource instanceof Array) ? pageInfo : false;
      } else if (key === "customRow") {
        props[key] = this[key] || this.onCustomRow;
      } else if (key === "columns") {
        props[key] = this.customColumns;
      } else {
        this[key] && (props[key] = this[key]);
      }
    });
    return (
      <div>
        {showAlert ? this.renderAlert() : null}
        <a-table
          {...{ props, scopedSlots: { ...this.$scopedSlots } }}
          onChange={onTableChange}
        >
          {Object.keys(this.$slots).map(name => (
            <template slot={name}>{this.$slots[name]}</template>
          ))}
        </a-table>
      </div>
    );
  }
};
</script>

<style scoped lang="less">
.table-alert {
  margin-bottom: 16px;
  .table-alert-info {
    display: flex;
    .table-alert-info-content {
      flex: 1 1;
    }
    .table-alert-info-option {
      min-width: 48px;
      padding-left: 16px;
    }
  }
  button[role="switch"] * {
    z-index: 999;
  }
  
}

</style>
